package com.itbuka.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.itbuka.cart.domain.Cart;
import com.itbuka.cart.feign.CartFeign;
import com.itbuka.goods.domain.GoodsProductDetails;
import com.itbuka.goods.feign.GoodsFeign;
import com.itbuka.order.config.RabbitMqConfig;
import com.itbuka.order.domain.Order;
import com.itbuka.order.domain.Task;
import com.itbuka.order.mapper.TaskMapper;
import com.itbuka.order.service.OrderService;
import com.itbuka.order.mapper.OrderMapper;
import com.itbuka.utils.TokenDecode;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private TokenDecode tokenDecode;
    @Autowired
    private TaskMapper taskMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private GoodsFeign goodsFeign;
    @Autowired
    private CartFeign cartFeign;

    @Override
    public List<Order> selectAll() {
        LambdaQueryWrapper<Order> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Order::getIsDelete, 0);
        return orderMapper.selectList(lqw);
    }

    @Override
    public List<Order> selectList(Order order) {
        LambdaQueryWrapper<Order> lqw = this.lqw(order);
        return orderMapper.selectList(lqw);
    }

    @Override
    @Transactional
    public Integer insert(Order order) {
        //查询库存是否足够
        GoodsProductDetails detailsSelect = new GoodsProductDetails();
        detailsSelect.setId(order.getProductId());
        GoodsProductDetails details = goodsFeign.select(detailsSelect).getData().get(0);
        if (details.getInventory() < order.getNum()) {
            return -1;
        }
        Date date = new Date();
        //下单
        order.setId(IdWorker.getId());
        order.setCreateTime(date);
        String userName = tokenDecode.getUserInfo().get("user_name");
        order.setBuyerName(userName);
        int insert = orderMapper.insert(order);
        if (insert != 1) {
            return -2;
        }
        //把要发送的信息存入task表中
        Task task = new Task();
        task.setId(IdWorker.getId());
        task.setTaskType("0");
        task.setMqExchange(RabbitMqConfig.ORDER_EXCHANGE);
        task.setMqRoutingkey(RabbitMqConfig.ORDER_QUEUE);
        task.setRequestBody(JSON.toJSONString(order));
        taskMapper.insert(task);
        //清除购物车
        cartFeign.delete(order.getProductId().toString());
        //发送消息
        rabbitTemplate.convertAndSend(RabbitMqConfig.ORDER_EXCHANGE, RabbitMqConfig.ORDER_QUEUE, JSON.toJSONString(task));
        //向死信队列发消息，超时未支付
        rabbitTemplate.convertAndSend("", RabbitMqConfig.PAY_QUEUE, JSON.toJSONString(order));
        return 1;
    }

    @Override
    @Transactional
    public Integer addCart(Map map) {
        List list = JSONObject.parseObject(JSON.toJSONString(map.get("cart")), List.class);
        Object addressId = map.get("addressId");
        Object shippingMethod = map.get("shippingMethod");
        for (Object o : list) {
            Cart cart = JSONObject.parseObject(JSON.toJSONString(o), Cart.class);
            Order order = new Order();
            order.setProductId(cart.getProductId());
            order.setMoney(cart.getMoney());
            order.setNum(cart.getNum());
            order.setAddressId(Long.valueOf(addressId.toString()));
            order.setShippingMethod(shippingMethod.toString());
            order.setSource(0);
            order.setType(0);
            this.insert(order);
        }
        return 1;
    }

    @Override
    public Integer clearCart(Map map) {
        List<Cart> data = cartFeign.findList().getData();
        map.put("cart", data);
        this.addCart(map);
        return 1;
    }

    @Override
    @Transactional
    public Integer delete(String ids) {
        try {
            String[] split = ids.split(",");
            for (String id : split) {
                Order order = new Order();
                order.setId(Long.parseLong(id));
                order.setIsDelete(1);
                orderMapper.updateById(order);
            }
            return 1;
        } catch (Exception e) {
            return -1;
        }
    }

    @Override
    public Integer update(Order order) {
        return orderMapper.updateById(order);
    }

    @Override
    public Page<Order> pageAll(Integer page, Integer size) {
        PageHelper.startPage(page, size);
        return (Page<Order>) this.selectAll();
    }

    @Override
    public Page<Order> pageList(Order order, Integer page, Integer size) {
        PageHelper.startPage(page, size);
        return (Page<Order>) this.selectList(order);
    }

    @Override
    @Transactional
    public void batchSend(List<Order> orders) {
        for (Order order : orders) {
            if (order.getId() == null) {
                throw new RuntimeException("订单号为空");
            }
            if (order.getShippingMethod() == null || order.getTrackingNumber() == null) {
                throw new RuntimeException("请选择快递公司和填写快递单号");
            }
            //进行状态校验
            Order order1 = orderMapper.selectById(order.getId());
            if (order1.getStatus() != 2) {
                throw new RuntimeException("订单状态不是待发货");
            }
            //修改订单状态
            order1.setStatus(3);
            order1.setShippingMethod(order.getShippingMethod());
            order1.setTrackingNumber(order.getTrackingNumber());
            order1.setUpdateTime(new Date());
            orderMapper.updateById(order1);
        }
        //给消息队列发消息
        rabbitTemplate.convertAndSend("",RabbitMqConfig.RECEIVING_QUEUE,JSON.toJSONString(orders));
    }

    @Override
    public void confirmTask(String orderId) {
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        if (order.getStatus() != 3) {
            throw new RuntimeException("订单状态异常");
        }
        order.setStatus(6);//已完成
        order.setUpdateTime(new Date());
        orderMapper.updateById(order);
    }

    public LambdaQueryWrapper<Order> lqw(Order order) {
        LambdaQueryWrapper<Order> lqw = new LambdaQueryWrapper<>();
        if (order.getId() != null) {
            lqw.eq(Order::getId, order.getId());
        }
        if (order.getSource() != null) {
            lqw.eq(Order::getSource, order.getSource());
        }
        if (order.getType() != null) {
            lqw.eq(Order::getType, order.getType());
        }
        if (order.getBuyerName() != null) {
            lqw.eq(Order::getBuyerName, order.getBuyerName());
        }
        if (order.getMoney() != null) {
            lqw.eq(Order::getMoney, order.getMoney());
        }
        if (order.getStatus() != null) {
            lqw.eq(Order::getStatus, order.getStatus());
        }
        if (order.getUpdateTime() != null) {
            lqw.eq(Order::getUpdateTime, order.getUpdateTime());
        }
        if (order.getCreateTime() != null) {
            lqw.eq(Order::getCreateTime, order.getCreateTime());
        }
        if (order.getIsDelete() != null) {
            lqw.eq(Order::getIsDelete, order.getIsDelete());
        }
        if (order.getAddressId() != null) {
            lqw.eq(Order::getAddressId, order.getAddressId());
        }
        if (order.getProductId() != null) {
            lqw.eq(Order::getProductId, order.getProductId());
        }
        if (order.getNum() != null) {
            lqw.eq(Order::getNum, order.getNum());
        }
        if (order.getTradeNo() != null) {
            lqw.eq(Order::getTradeNo, order.getTradeNo());
        }
        return lqw;
    }
}